using Model;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace EFDAL
{
    public class BaseDal<T> where T : class, new()
    {
        private DbContext db;

        public BaseDal()
        {
            db = DbContextFactory.GetCurrentDbContext();
        }

        #region CUD
        public T Add(T entity)
        {
            db.Set<T>().Add(entity);
            return entity;
        }
        public bool Update(T entity)
        {
            db.Entry(entity).State = EntityState.Modified;
            return true;
        }
        public bool Update(T entity, string[] arr)
        {
            //1.通过反射动态获取属性判断属性是否为null进行按需更新（灵活，效率低）
            //db.Entry(entity).State = EntityState.Unchanged;
            //foreach (var i in entity.GetType().GetProperties().Where(p => p.CanRead && p.CanWrite && !p.GetMethod.IsVirtual))
            //{
            //    string name = i.Name;
            //    object value = i.GetValue(entity);
            //    if (value != null)
            //    {
            //        db.Entry(entity).Property(name).IsModified = true;
            //    }
            //}
            //2.根据传入的属性名称进行按需更新
            //问题：为何db.Entry(entity)之后需要设置成Unchanged状态。
            //因为可能说在db共用一个的情况下，entity是被db所跟踪的（之前是通过此db获取的）,此时的状态可能是Modified。此种
            //情况下我们强制设置为Unchanged，然后再根据其具体需求对属性设置IsModified状态。
            db.Entry(entity).State = EntityState.Unchanged;
            foreach (string item in arr)
            {
                db.Entry(entity).Property(item).IsModified = true;
            }
            return true;
        }

        public bool Delete(T entity)
        {
            db.Entry(entity).State = EntityState.Deleted;
            return true;
        }
        #endregion

        #region 查询

        public IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda)
        {
            return db.Set<T>().Where(whereLambda);
        }

        #endregion
    }
}
